package com.epin.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;


public class FileUtils {

    /**
    * 读取返回文件内容：默认UTF-8编码方式读取
    * @Title readTxtFile 
    * @Description 读取返回文件内容
    * @param file
    * @param encoding
    * @return
    * @throws IOException 参数说明 
    * @return String 返回类型 
    * @throws IOException 
    */
    public static String readTxtFile(String filePath) throws IOException {
		StringBuffer txt = new StringBuffer();
		String encoding = "UTF-8";
		File file = new File(filePath);
		txt.append(readTxtFile(file, encoding));
		return txt.toString();
	}
    
    /**
     * 读取返回文件内容
    * @Title readTxtFile 
    * @Description 读取返回文件内容
    * @param file
    * @param encoding
    * @return
    * @throws IOException 参数说明 
    * @return String 返回类型 
    * @throws
     */
    public static String readTxtFile(File  file,String encoding) throws IOException {
		StringBuffer txt = new StringBuffer();
		InputStreamReader read = null;
		try{
			if (file.isFile() && file.exists()) { // 判断文件是否存在
				read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式
				BufferedReader bufferedReader = new BufferedReader(read);
				String lineTxt = null;
				while ((lineTxt = bufferedReader.readLine()) != null) {
					txt.append(lineTxt);
				}
			} else {
				//System.out.println("找不到指定的文件");
			}
		}finally {
			if(null != read) {
        		try{
        			read.close();
        		}catch (IOException e){
        			e.printStackTrace();
        		}
        	}
		}
		return txt.toString();
	}
    
    /**  
     * 下载远程文件并保存到本地  
     * @param remoteFileUrl 远程文件路径   
     * @param localFilePath 本地文件路径  
     * @throws IOException 
     * @throws Exception 
     */
    public static void downloadFile(String remoteFileUrl, String localFilePath) throws IOException {
        URL urlfile = null;
        HttpURLConnection httpUrl = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        File localFile = new File(localFilePath);
        
        try{
            urlfile = new URL(kgReplace(remoteFileUrl));
            httpUrl = (HttpURLConnection)urlfile.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());
            if (!localFile.exists()&&localFilePath.indexOf(".")>0) {
            	localFile.mkdirs();
			}else {
				if(!localFile.getParentFile().exists()){
					localFile.getParentFile().mkdirs();
				}
			}
            bos = new BufferedOutputStream(new FileOutputStream(localFile));
            int len = 2048;
            byte[] b = new byte[len];
            while ((len = bis.read(b)) != -1){
                bos.write(b, 0, len);
            }
            bos.flush();
            bis.close();
            httpUrl.disconnect();
        }finally{
        	if(null != bis) {
        		try{
        			bis.close();
        		}catch (IOException e){
        			e.printStackTrace();
        		}
        	}
            if(null != bos) {
            	try{
            		bos.close();
            	}catch (IOException e){
            		e.printStackTrace();
            	}
            }
        }
    }
    
    /**
     * @Title getBytes 
     * @Description 获取文件的bytes形式信息
     * @param file
     * @return
     */
    public static byte[] getBytes(File file){
		if(file!=null && file.exists() && file.isFile()){
			byte[] buffer = null;
			FileInputStream fis = null;
			ByteArrayOutputStream bos = null;
			try {
				fis = new FileInputStream(file);
				bos = new ByteArrayOutputStream(1000);
				byte[] b = new byte[1000];
				int n;
				while ((n = fis.read(b)) != -1) {
					bos.write(b, 0, n);
				}
				buffer = bos.toByteArray();
				return buffer;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (fis != null) {
						fis.close();
					}
					if (bos != null) {
						bos.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
    
	public static void copyFile(InputStream inputFileStream,String outputFile) throws FileNotFoundException{
		File tFile = new File(outputFile);
		FileOutputStream fos = new FileOutputStream(tFile);
		int temp = 0;  
        try {  
			while ((temp = inputFileStream.read()) != -1) {  
			    fos.write(temp);  
			}
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally{
            try {
				inputFileStream.close();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
        } 
	}
	
	public static String kgReplace(String url){
		if(!StringUtils.isEmpty(url)){
			return url.replaceAll(" ", "%20");
	    }
	    return url;
	}
	
	/** 读取Excel文件的数据,组装成一个Map(key=行*列) **/
	public static Map<String, Object> readExcelData(File file, String sheetName){
		if(file!=null){
			InputStream is  = null;
			String fileName = "";
			try {
				is = new FileInputStream(file);
				fileName = file.getName();
				return readExcelData(is, fileName, sheetName);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} finally{
				if(is!=null){
					try {
						is.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		return null;
	}
	
	/** 读取Excel文件的数据,组装成一个Map(key=行*列) **/
	public static Map<String, Object> readExcelData(InputStream is, String fileName, String sheetName){
		if(is!=null && StringUtils.isNotBlank(fileName)){
			String fileType = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
			if("xls".equals(fileType) || "xlsx".equals(fileType)){
				try {
					Workbook wb = null;
					FormulaEvaluator evaluator = null;
					if (fileType.equals("xls")) {
						wb = new HSSFWorkbook(is);
						evaluator = new HSSFFormulaEvaluator((HSSFWorkbook) wb);
					} else if (fileType.equals("xlsx")) {
						wb = new XSSFWorkbook(is);
						evaluator = new XSSFFormulaEvaluator((XSSFWorkbook) wb);
					}
					//默认读取 第一个Sheet 的内容; 如果传递进来一个Sheet的名称,则读取指定名称的Sheet的内容
					Sheet sheet = null;
					if(StringUtils.isNotBlank(sheetName)){
						sheet = wb.getSheet(sheetName);
					}else{
						sheet = wb.getSheetAt(0);
					}
					if(sheet!=null){
						int rowNum = sheet.getPhysicalNumberOfRows();//获取的是物理行数，也就是不包括那些空行（隔行）的情况
						//System.out.println(fileName+"物理行数:"+rowNum);
						//当前Sheet存在内容
						if(rowNum>0){
							SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); 
							Map<String, Object> result = new HashMap<String, Object>();
							Iterator<Row>  row_iterator  = sheet.iterator();//Iterator<Row>  row_iterator  = sheet.rowIterator();
							Iterator<Cell> cell_iterator = null;
							Row  row  = null;
							Cell cell = null;
							Object obj = null;
							while(row_iterator.hasNext()){
								row = row_iterator.next();
								//System.out.println(fileName+"-Row-Index:"+(row.getRowNum()+1));
								cell_iterator = row.iterator();//cell_iterator = row.cellIterator();
								while(cell_iterator.hasNext()){
									cell = cell_iterator.next();
									int index_row    = cell.getRowIndex()+1;
									int index_column = cell.getColumnIndex()+1;
									if(cell == null){
										obj = "";
									}else if(cell.getCellType() == Cell.CELL_TYPE_BLANK){
										obj = "";
									}else if(cell.getCellType() == Cell.CELL_TYPE_STRING){
										obj = cell.getRichStringCellValue().toString();
									}else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
										if (HSSFDateUtil.isCellDateFormatted(cell)) {
											Date date = cell.getDateCellValue();
											obj = sdfDate.format(date);
										} else {
											NumberFormat nf = NumberFormat.getInstance();
											nf.setMaximumFractionDigits(6);//设置保留小数位6(似乎默认是保留3位小数)
											nf.setGroupingUsed(false);//true时的格式：1,234,567,890
											obj = nf.format(cell.getNumericCellValue());
										}
										
									}else if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){
										//obj = cell.getCellFormula();
										CellValue cellV = evaluator.evaluate(cell);
										double iCellValue = cellV.getNumberValue();
										obj = String.valueOf(iCellValue);
									}else if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){
										obj = (Boolean)cell.getBooleanCellValue();
									}else if(cell.getCellType() == Cell.CELL_TYPE_ERROR){
										obj = "";
									}
									//System.out.println(fileName+"第"+(row.getRowNum()+1)+"行第"+(cell.getColumnIndex()+1)+"列:"+obj);
									//将Excel数据按照 单元格(标注行列位置) 数据存储到Map里
									result.put(index_row+"*"+index_column, obj);
									
									obj = null;
									cell = null;
								}
								cell_iterator = null;
								row  = null;
							}
							return result;
						}
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally{
					if(is!=null){
						try {
							is.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		return null;
	}
	
	/** 读取Excel里指定 行列 位置的数据  **/
	public static String getValueFromExcelDataMap(Map<String, Object> map, int i, int j){
		if(map!=null && !map.isEmpty()){
			String key = (i+"*"+j);
			if(map.containsKey(key)){
				Object value = map.get(key);
				if(value!=null){
					return (""+value).trim();
				}
			}
		}
		return "";
	}
	
	/** 查找Excel里第几列的内容为指定的value  **/
	public static int getMarkPositionOfStr(Map<String, Object> map, String value, int n){
		if(map!=null && !map.isEmpty() && StringUtils.isNotBlank(value) && n>0){
			Set<String> ss = map.keySet();
			Iterator<String> itt = ss.iterator();
			while(itt.hasNext()){
				String kk = itt.next();
				Object kv = map.get(kk);
				if(StringUtils.isNotBlank(kk) && kk.endsWith("*"+n)){
					if(kv!=null){
						String temp = (""+kv).trim();
						if(StringUtils.isNotBlank(temp) && temp.equals(value.trim())){
							String mark = kk.substring(0, kk.indexOf("*"));
							//System.out.println("mark:"+mark);
							if(StringUtils.isNotBlank(mark)){
								return Integer.valueOf(mark);
							}
						}
					}
				}
			}
		}
		return -1;
	}
	
	/** 通用:将指定的服务器上文件进行下载  **/
	public static void downloadExcle(File file, HttpServletRequest request,HttpServletResponse response, String exportfileName) {
		BufferedInputStream fis = null;
		OutputStream toClient = null;
		try {
			fis = new BufferedInputStream(new FileInputStream(file.getPath()));
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
			response.reset();
			toClient = new BufferedOutputStream(response.getOutputStream());
			
			String agent = request.getHeader("USER-AGENT").toLowerCase();
		    //根据浏览器类型处理文件名称
		    if(agent.indexOf("msie")>-1){
		    	exportfileName = URLEncoder.encode(exportfileName, "UTF-8");
		    }else{  //firefox/safari不转码
		    	exportfileName = new String(exportfileName.getBytes("UTF-8"), "ISO8859-1");
		    }
		    response.setContentType("application/msexcel");
		    response.setHeader("Content-disposition","attachment;filename=\""+exportfileName+"\"");
			
			toClient.write(buffer);
			toClient.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭下载输出流
			if (toClient != null) {
				try {
					toClient.close();
				} catch (IOException ex1) {
					ex1.printStackTrace();
				}
			}
			// 关闭读取输入流
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException ex2) {
					ex2.printStackTrace();
				}
			}
			// 将生成的服务器端文件删除
			if (file != null && file.exists()) {
				file.delete();
			}
		}
	}
	   
}
